//
//  PromiseResult.swift
//  SwiftUILean
//
//  Created by wyknmjj on 2024/5/13.
//

import Foundation


enum PromiseResult<T>{
    case success(data:T)
    case error(Error)
}

struct VersionData<T>{
    let version:Int
    let data:T
}

typealias VersionPromiseResult<T>=VersionData<VersionData<PromiseResult<T>>>

func initResult<T>(_ v:T) -> VersionPromiseResult<T>{
    return VersionData(
        version: 0,
        data: VersionData(
            version: 0,
            data: PromiseResult.success(data: v)))
}


func reduceResult<T>(_ fun:() async throws ->T,
                    getValue:()->VersionPromiseResult<T>,
                     setValue:(VersionPromiseResult<T>)->Void) async{
    let value=getValue()
    let newVersion = value.version + 1
    setValue(VersionData(version: newVersion, data: value.data))
    do{
        let result = try await fun()
        if(getValue().version==newVersion){
            setValue(VersionData(
                version: newVersion,
                data: VersionData(
                    version: newVersion,
                    data:.success(data: result))))
        }
    }catch{
        if(getValue().version==newVersion){
            setValue(VersionData(
                version: newVersion,
                data: VersionData(
                    version: newVersion,
                    data: .error(error))))
        }
    }
}


